unit uEngine;

interface
uses
  Forms, SysUtils, Classes, Windows,
  GlScene, GlObjects, GLCadencer, GLWin32Viewer,GLRenderContextInfo, GlMaterial,
  uTweener, GLControl, PackManager,GLWindowsFont, uAbstractMenu;

type
  TEngine = class
  private
    {Scene}
    fGlScene: TGlScene;
    fCadencer: TGLCadencer;
    fViewer: TGLSceneViewer;
    fCamera: TGlCamera;
    fMainDummy: TGlDummyCube;
    fFpsTimer: Single;
    fMatLib: TGlMaterialLibrary;
    {Tweener}
    fTweener: TTweener;
    {Controls}
    FControlList : TList;
    {Engine}
    fPkManager : TPackManager;
    fInitialized : Boolean;
    fForm : TForm;
    Procedure OnCadencerProgress(Sender : TObject; const deltaTime, newTime : Double);
    procedure FormActivate(Sender: TObject);
    procedure FormDeActivate(Sender: TObject);
  public
    constructor Create;
    destructor Destroy; override;
    procedure InitForm(const aForm: TForm);
    function AddMaterial(fStream: TStream; aMaterialName: String): TGlLibMaterial; overload;
    function GetFont(FontId:integer):TGLWindowsBitmapFont;
    {Controls}
    function ControlAdd(aControl : TGLControlClass):TGLControl;
    procedure ControlRemove(aControl : TGLControl);
  published
    property Form: TForm read fForm;
    property Dummy: TGlDummyCube read fMainDummy;
    property Tweener: TTweener read fTweener;
    property MatLib: TGlMaterialLibrary read fMatLib;
  end;
var
  Engine : TEngine;

implementation
uses Controls, Graphics, GlTexture, GlCompositeImage, GlFilePNG,
GlFileJPeG,uGraphicFunctions,glKeyboard, GLCrossPlatform,uFonts;

Function RGB(r, g, b: byte): TColor;
begin
  result := r + (g shl 8) + b shl 16;
end;
{ TEngine }

function TEngine.AddMaterial(fStream: TStream;
  aMaterialName: String): TGlLibMaterial;
begin
  Result:=uGraphicFunctions.AddMaterial(fMatLib,fStream, aMaterialName);
end;

function TEngine.ControlAdd(aControl: TGLControlClass): TGLControl;
begin
  Result:=aControl.CreateAsChild(fMainDummy);
  Result.Material.MaterialLibrary := fMatLib;
  FControlList.Add(Result);
end;

procedure TEngine.ControlRemove(aControl: TGLControl);
begin
  FControlList.Remove(aControl);
  aControl.Free;
end;

constructor TEngine.Create;
begin
   inherited;
   fTweener := TTweener.Create;
   FControlList := TList.Create;
   fPkManager:=TPackManager.Create;
end;

destructor TEngine.Destroy;
begin
  FreeAndNil(fPkManager);
  FreeAndNil(fTweener);
  FreeAndNil(FControlList);
  inherited;
end;

procedure TEngine.FormActivate(Sender: TObject);
begin
  fCadencer.Enabled := true;
end;

procedure TEngine.FormDeActivate(Sender: TObject);
begin
  fCadencer.Enabled := false;
end;

function TEngine.GetFont(FontId: integer): TGLWindowsBitmapFont;
begin
  Result:=uFonts.GetFont(FontId);
end;

procedure TEngine.InitForm(const aForm: TForm);
var
  tmp_mem:TStream;
  i : Integer;
begin
  fForm := aForm;
  fForm.OnActivate := FormActivate;
  fForm.OnDeactivate:=FormDeActivate;
  fGlScene := TGlScene.Create(fForm);
  fCadencer := TGLCadencer.Create(fForm);
  AddFont(fForm,C_FONT_1);
  AddFont(fForm,C_FONT_2);
  with fCadencer do
  begin
    Enabled := false;
    SleepLength := 5;
    Mode := cmApplicationIdle;
    Scene := fGlScene;
  end;
  fViewer := TGLSceneViewer.Create(fForm);
  fViewer.Buffer.BackgroundColor :=  RGB(60, 60, 60);
  with fViewer do
  begin
    Parent := aForm;
    fViewer.Align := alClient;
  end;
  fCamera := TGlCamera.CreateAsChild(fGlScene.Objects);
  with fCamera do
  begin
    Position.SetPoint(0, 0, 5);
    Direction.SetVector(0, 0, -1);
    Up.SetVector(0, 1, 0);
    CameraStyle := csOrthogonal;
    SceneScale := 0.1;
  end;
    fMainDummy := TGLDummyCube.CreateAsChild(fGlScene.Objects);
  fMainDummy.ObjectsSorting := osNone;

  fViewer.Camera := fCamera;
  fCadencer.OnProgress := OnCadencerProgress;

  fMatLib := TGlMaterialLibrary.Create(fForm);
  fPkManager.readBaseFile;
  for I := 0 to fPkManager.FilesInfo.Count-1 do
  begin
    tmp_mem:=fPkManager.GetFileByIndex(i);
    Self.AddMaterial(tmp_mem,fPkManager.FilesInfo[i].name);
    tmp_mem.Free;
  end;

end;

procedure TEngine.OnCadencerProgress(Sender: TObject; const deltaTime,
  newTime: Double);
var
  i : integer;
  MPos: TPoint;
begin
   fTweener.Update(deltaTime);

  GetCursorPos(Mpos);
  MPos := fViewer.ScreenToClient(MPos);
  for I := 0 to FControlList.Count - 1 do
  if FControlList.Count > i then
  TGLControl(FControlList[i]).SetMouseState(MPos.X, MPos.Y, IsKeyDown(Vk_LButton));
  fViewer.Invalidate;
end;

initialization
  Engine := TEngine.Create;

finalization
  Engine.Free;

end.
